﻿using battle;
using CustomDataStruct;
using ProtoBuf.Serializers;
using System.IO;
using com.youzu.warh.protocol;
using Yoozoo.Framework.Core;

/// <summary>
/// 说明：ProtoBuf初始化、缓存等管理；序列化、反序列化等封装
/// 
/// @by wsh 2017-07-01
/// </summary>

public class ProtoBufSerializer : Singleton<ProtoBufSerializer>
{
    ProtoBuf.Meta.RuntimeTypeModel model;

    public override void Initialize(Options options=null)
    {
        base.Initialize(options);
        #if UNITY_EDITOR
        Dispose();
        #endif
        model = ProtoBuf.Meta.RuntimeTypeModel.Default;
        AddCustomSerializer();
        AddProtoPool();
        model.netDataPoolDelegate = ProtoFactory.Get;
        model.bufferPoolDelegate = StreamBufferPool.GetBuffer;
    }

    public override void Dispose()
    {
        model = null;
        ClearCustomSerializer();
        ClearProtoPool();
    }

    static public void Serialize(Stream dest, object instance)
    {
        ProtoBufSerializer.GetInstance().model.Serialize(dest, instance);
    }

    static public object Deserialize(Stream source, System.Type type, int length = -1)
    {
        return ProtoBufSerializer.GetInstance().model.Deserialize(source, null, type, length, null);
    }

    void AddCustomSerializer()
    {
        // 自定义Serializer以避免ProtoBuf反射
        CustomSetting.AddCustomSerializer(typeof(ArenaBattleReport), new ArenaBattleReportDecorator());
        CustomSetting.AddCustomSerializer(typeof(ArenaReportContent), new ArenaReportContentDecorator());
        CustomSetting.AddCustomSerializer(typeof(SCRoundFight), new SCRoundFightDecorator());
        CustomSetting.AddCustomSerializer(typeof(TroopFightInfo),new TroopFightInfoDecorator());
        CustomSetting.AddCustomSerializer(typeof(CastAreaSkill),new CastAreaSkillDecorator());
        CustomSetting.AddCustomSerializer(typeof(SiegeFightInfo),new SiegeFightInfoDecorator());
        CustomSetting.AddCustomSerializer(typeof(CastSkill),new CastSkillDecorator());
        CustomSetting.AddCustomSerializer(typeof(EffectElement),new EffectElementDecoator());
//        CustomSetting.AddCustomSerializer(typeof(ElementResult),new ElementResultDecorator());
        CustomSetting.AddCustomSerializer(typeof(BattleMountUnit),new BattleMountUnitDecorator());
        CustomSetting.AddCustomSerializer(typeof(PlunderResResult),new PlunderResResultDecorator());
        CustomSetting.AddCustomSerializer(typeof(DisplayResource),new DisplayResourceDecorator());
        CustomSetting.AddCustomSerializer(typeof(MapUnit),new MapUnitDecorator());
        CustomSetting.AddCustomSerializer(typeof(Coordinate),new CoordinateDecorator());
        CustomSetting.AddCustomSerializer(typeof(CastDamage),new CastDamageDecorator());
    }

    void ClearCustomSerializer()
    {
        CustomSetting.CrearCustomSerializer();
    }


    void AddProtoPool()
    {
        // 自定义缓存池以避免ProtoBuf创建实例
        ProtoFactory.AddProtoPool(typeof(ArenaBattleReport),new ArenaBattleReportPool());
        ProtoFactory.AddProtoPool(typeof(ArenaReportContent),new ArenaReportContentPool());
        ProtoFactory.AddProtoPool(typeof(SCRoundFight), new SCRoundFightPool());
        ProtoFactory.AddProtoPool(typeof(TroopFightInfo),new TroopFightInfoPool());
        ProtoFactory.AddProtoPool(typeof(CastAreaSkill),new CastAreaSkillPool());
        ProtoFactory.AddProtoPool(typeof(SiegeFightInfo),new SiegeFightInfoPool());
        
        ProtoFactory.AddProtoPool(typeof(MapUnit),new MapUnitPool());
        ProtoFactory.AddProtoPool(typeof(CastSkill),new CastSkillPool());
        ProtoFactory.AddProtoPool(typeof(Coordinate),new CoordinatePool());
        
        ProtoFactory.AddProtoPool(typeof(EffectElement),new EffectElementPool());
//        ProtoFactory.AddProtoPool(typeof(ElementResult),new ElementResultPool());
        ProtoFactory.AddProtoPool(typeof(BattleMountUnit),new BattleMountUnitPool());
        ProtoFactory.AddProtoPool(typeof(PlunderResResult),new PlunderResResultPool());
        ProtoFactory.AddProtoPool(typeof(DisplayResource),new DisplayResourcePool());
        ProtoFactory.AddProtoPool(typeof(CastDamage),new CastDamagePool());
    }

    void ClearProtoPool()
    {
        ProtoFactory.ClearProtoPool();
    }
}
